package com.ivanceras.client.view;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.RichTextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.ivanceras.client.Choice;
import com.ivanceras.client.SimulationService;
import com.ivanceras.client.SimulationServiceAsync;
import com.ivanceras.client.Question;
import com.ivanceras.client.text.RichTextToolbar;



public class QuestionEdit implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public String text;
	public int questionNo;
	public long questionnaireKey;
	final RichTextArea area  = new RichTextArea();
	VerticalPanel widget =  new VerticalPanel();
	VerticalPanel choicePanel = new VerticalPanel();
	private HandlerRegistration registration = null;
	public QuestionnaireViewer questionnaireViewer;
	
	public ArrayList<ChoiceEdit> choiceList =  new ArrayList<ChoiceEdit>();
	final Button saveButton = new Button("Save");
	public Question question;

    final private String areaCaption = "Add question...";
	
	private final SimulationServiceAsync simulationService = GWT
	.create(SimulationService.class);

	public QuestionEdit(){
		createDefaultChoices();
		HorizontalPanel hpanel = new HorizontalPanel();
		
		hpanel.add(createRichTextEditor());
		widget.add(hpanel);
		widget.setWidth("100%");
		widget.add(choicePanel);
		choicePanel.setWidth("100%");
		//saveButton.setVisible(true);
		saveButton.setEnabled(false);
		saveButton.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event) {
				if(question == null){
					addNewQuestion();
				}else{
					saveQuestion();
				}
			}
			
		});
		widget.add(saveButton);
	}
	public QuestionEdit(long questionnaireKey, Question question){
		this();
		this.question = question;
		this.questionnaireKey = questionnaireKey;
		this.area.setHTML(question.text);
		choicePanel.clear();
		for(Choice ch : question.choiceList ){
			ChoiceEdit ce = new ChoiceEdit();
			ce.textBox.setText(ch.text);
			ce.isCorrect = ch.isCorrect;
			addChoiceEdit(ce);
		}
	}
	public QuestionEdit(long questionnaireKey){
		this();
		this.questionnaireKey = questionnaireKey;
	}
	public void saveQuestion(){
		simulationService.saveQuestion(question, new AsyncCallback<Question>(){

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("There was an error saving the question!");
			}

			@Override
			public void onSuccess(Question result) {
				Window.alert("Question saved!");
			}
			
		});
	}

	public void addNewQuestion(){
		String questionText = area.getHTML();
		ArrayList<Choice> qcList = new ArrayList<Choice>();
		for(int i = 0; i< choiceList.size(); i++){
			ChoiceEdit ce = choiceList.get(i);
			if(ce.isOfficial()){ //don't add unofficial choices
				Choice qc = new Choice();
				qc.text = ce.getText();
				qc.isCorrect = ce.isCorrect;
				qcList.add(qc);
			}
		}
		simulationService.addNewQuestion(QuestionEdit.this.questionnaireKey, questionText, qcList, new AsyncCallback<Question>(){
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Something went wrong!\n"+caught.getMessage());
				
			}
			@Override
			public void onSuccess(Question question) {
				//Window.alert("Question Added!");
				question.itemNo = new Long(questionnaireViewer.questionViewers.size()+1);
				questionnaireViewer.lastItem.setHTML("<b>"+(question.itemNo+1)+"</b>.");
				//System.out.println("viewer size:"+questionnaireViewer.questionViewers.size());
				questionnaireViewer.addQuestion(question);
				questionnaireViewer.questionCreator.clear();
			}
			
		});
	}
	public void clear(){
		area.setHTML(areaCaption);
		clearChoices();
		createDefaultChoices();
	}
	public void createDefaultChoices(){
		for(int i = 0; i < 4; i++){
			ChoiceEdit ce = new ChoiceEdit();
			ce.setOfficial(true);//set the first 4 official
			addChoiceEdit(ce);
		}
	}
	public void clearChoices(){
		choiceList.clear();
		choicePanel.clear();
	}
	public Widget createRichTextEditor(){
		/**
		 * create the richtext editor
		 */
	    //area.setStyleName("new-question");
	    area.setHeight("40px");
	    area.setWidth("100%");
	    area.setHTML(areaCaption);
	    final RichTextToolbar toolbar = new RichTextToolbar(area);
	    toolbar.setWidth("100%");
	    toolbar.setVisible(false);
	    area.addFocusHandler(new FocusHandler(){
			@Override
			public void onFocus(FocusEvent event) {
				area.setHeight("150px");
				toolbar.setVisible(true);
				if(area.getHTML().equals(areaCaption)){
					area.setHTML("");
				}
			}
	    	
	    });
	    area.addKeyUpHandler(new KeyUpHandler(){ //use the keyup event to include copy and paste
			@Override
			public void onKeyUp(KeyUpEvent event) {
				int length = area.getText().length();
				if(length > 1){//show the save button when the user has type at least 5 characters
					//saveButton.setVisible(true);
					saveButton.setEnabled(true);
				}
			}
	    });
	    // Add the components to a panel
	    Grid grid = new Grid(2, 1);
	    grid.setStyleName("cw-RichText");
	    grid.setWidget(0, 0, toolbar);
	    grid.setWidget(1, 0, area);
	    return grid;
	}
	public class QuestionEditKeyPressHandler implements KeyPressHandler{
		@Override
		public void onKeyPress(KeyPressEvent event) {
			final ChoiceEdit choiceEdit = new ChoiceEdit();
			final String choiceCaption =  "add more choices...";
			choiceEdit.setOfficial(false);
			choiceEdit.textBox.setText(choiceCaption);
			choiceEdit.textBox.addFocusHandler(new FocusHandler(){

				@Override
				public void onFocus(FocusEvent event) {
					if(choiceEdit.textBox.getText().equals(choiceCaption)){
						choiceEdit.textBox.setText("");
						choiceEdit.setOfficial(true);
					}
				}
			});
			addChoiceEdit(choiceEdit);
		}
		
	}
	public void addChoiceEdit(ChoiceEdit choiceEdit){
		choiceEdit.questionNo = questionNo; 
		choiceList.add(choiceEdit);
		choicePanel.add(choiceEdit.getWidget());
		HTML separator = new HTML();
		separator.setHeight("5px");
		choicePanel.add(separator);

		KeyPressHandler qeHandler = new QuestionEditKeyPressHandler();
		if(null != registration){ //remove the registration from preceeding choices
			registration.removeHandler();
		}
		registration = choiceEdit.textBox.addKeyPressHandler(qeHandler); //then attach a new event to the current, last

	}
	public List<ChoiceEdit> getChoices(){
		return choiceList;
	}
	public Widget getWidget(){
		return widget;
	}
}
